package com.vshop.framework.core.autoconfig;

import com.vshop.framework.core.spring.SpringContextUtil;
import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.core.task.VirtualThreadTaskExecutor;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;

import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.concurrent.Executor;

/**
 * *异步配置
 * <p>
 * 如果未使用虚拟线程则生效
 */
@Slf4j
@EnableAsync
@AutoConfiguration
public class AsyncAutoConfig implements AsyncConfigurer {
    @PostConstruct
    public void postConstruct() {
        log.info("初始化 AsyncAutoConfig");
    }


    /**
     * 线程池 配置bean名称
     */
    public static final String ASYNC_EXECUTOR_THREAD_NAME = "default-async-executor";

//    @Bean(name = ASYNC_EXECUTOR_THREAD_NAME)
//    public Executor executor() {
//
//        // 父子线程共享 MDC
//        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
//        executor.setTaskDecorator(runnable -> {
//            Map<String, String> context = MDC.getCopyOfContextMap();
//            return () -> {
//                try {
//                    if (context != null) {
//                        MDC.setContextMap(context);
//                    }
//                    runnable.run();
//                } finally {
//                    // 清除子线程的，避免内存溢出，就和ThreadLocal.remove()一个原因
//                    MDC.clear();
//                }
//            };
//        });
//
////        int corePoolSize = 10;
////        int maxPoolSize = 50;
//        int corePoolSize = Runtime.getRuntime().availableProcessors();
//        int maxPoolSize = Runtime.getRuntime().availableProcessors() * 2;
//        int queueCapacity = 1000;
//        int keepAliveSeconds = 180;
//
//        // 设置核心线程数
//        executor.setCorePoolSize(corePoolSize);
//        // 设置最大线程数
//        executor.setMaxPoolSize(maxPoolSize);
//        // 设置队列容量
//        executor.setQueueCapacity(queueCapacity);
//        // 设置线程活跃时间（秒）
//        executor.setKeepAliveSeconds(keepAliveSeconds);
//        executor.setThreadNamePrefix(ASYNC_EXECUTOR_THREAD_NAME);
//        // 等待所有任务结束后再关闭线程池
//        executor.setWaitForTasksToCompleteOnShutdown(true);
//        executor.setAwaitTerminationSeconds(60);
//        // 设置拒绝策略
//        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
//
//        executor.initialize();
//
//        return TtlExecutors.getTtlExecutor(executor);
//    }

    @Override
    public Executor getAsyncExecutor() {
//        return executor();
        if (SpringContextUtil.isVirtual()) {
            return new VirtualThreadTaskExecutor("virtual-async-");
        }
        return SpringContextUtil.getBean("scheduledExecutorService");
    }

    /**
     * spring 异步任务 异常配置
     */
    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        return new AsyncExceptionHandler();
    }


    /**
     * 自定义异常处理
     */
    public static class AsyncExceptionHandler implements AsyncUncaughtExceptionHandler {
        @Override
        public void handleUncaughtException(Throwable throwable, Method method, Object... objects) {
            log.error("异步任务发生异常:{}, 参数:{}, ", method.getDeclaringClass().getSimpleName()
                    + "." + method.getName(), Arrays.toString(objects), throwable);

//            StringBuilder sb = new StringBuilder();
//            sb.append("Exception message - ").append(throwable.getMessage())
//                    .append(", Method name - ").append(method.getName());
//            if (ArrayUtil.isNotEmpty(objects)) {
//                sb.append(", Parameter value - ").append(Arrays.toString(objects));
//            }
//            throw new ServiceException(sb.toString());
        }
    }

}
